//
//  XLConversationVoiceRecordView.m
//  XLConversationInputView
//
//  Created by ilongge on 2022/8/30.
//

#import "XLConversationInputVoiceRecordView.h"
#import "XLCIViewResourcesManager.h"
#import "XLConversationInputViewDef.h"
#import "XLCAudioRecorder.h"
#import "XLCvstInputMoreItemModel.h"
#import "XLCvstInputMoreItemModel+Inside.h"

@interface XLConversationInputVoiceRecordView()
@property (nonatomic, strong) UILabel *cancleLabel;
@property (nonatomic, strong) UILabel *tipLabel;
@property (nonatomic, strong) UIView *voiceBackgroundView;
@property (nonatomic, strong) UIView *backgroundView;
@property (nonatomic, strong) UIImageView *voiceRecordGifView;
@property (nonatomic, strong) NSMutableArray *animationImages;
@property (nonatomic, assign) NSInteger animationRepeatCount;
@property (nonatomic, assign) BOOL recoreding;
@property (nonatomic, assign) float animationDuration;
@property (nonatomic, strong) XLCAudioRecorder *audioRecorder;
@property (nonatomic, strong) XLCvstInputMoreItemModel *voiceItem;
@property (nonatomic, assign) CGRect recordRect;
@end
@implementation XLConversationInputVoiceRecordView

- (instancetype)initWithRootPath:(NSString *)rootPath
{
    self = [super init];
    if (self) {
        _maxVoiceDuration = 60.f;
        _minVoiceDuration = 2.0f;
        if (rootPath.length == 0) {
            NSString* cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
            cachesDirectory = [cachesDirectory stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
            rootPath = [NSString stringWithFormat:@"%@/VoiceRecoredCache", cachesDirectory];
        }
        _rootPath = rootPath;
        NSFileManager *filemanager = [NSFileManager defaultManager];
        BOOL ret = [filemanager fileExistsAtPath:rootPath];
        if (ret == NO) {
            NSError *error = nil;
            BOOL result = [filemanager createDirectoryAtPath:rootPath
                                 withIntermediateDirectories:YES
                                                  attributes:@{}
                                                       error:&error];
            if (error || result == NO) {
                NSLog(@"create cache directory fail: %@", rootPath);
            }
        }
        [self initSubViews];
    }
    return self;
}

- (void)initSubViews {
    [[[UIApplication sharedApplication]delegate].window addSubview:self.backgroundView];
    [self addSubview:self.voiceBackgroundView];
    [self.voiceBackgroundView addSubview:self.voiceRecordGifView];
    [self addSubview:self.cancleTipLabel];
    [self addSubview:self.cancleLabel];
    [self addSubview:self.tipLabel];
    NSBundle *bundle = [XLCIViewResourcesManager XLCIResourcesBundle];
    NSString *pathString = [bundle pathForResource:@"voiceRecord" ofType:@"gif"];
    NSURL *url = [NSURL fileURLWithPath:pathString];
    [self loadGIFImageNamed:url];
    [self hiddenSubviews:YES];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(stopVoiceRecord)
                                                 name:UIApplicationWillResignActiveNotification
                                               object:nil];
}

- (void)returnToStart {
    [self hiddenSubviews:YES];
    self.alpha = 1;
}

- (void)hiddenSubviews:(BOOL)hidden {
    NSArray *subviews = self.subviews;
    for (NSInteger index = 0; index < subviews.count; index++) {
        UIView *view = subviews[index];
        view.hidden = hidden;
    }
    self.backgroundView.hidden = hidden;
}

-(void)setMaxVoiceDuration:(float)maxVoiceDuration
{
    _maxVoiceDuration = maxVoiceDuration;
}
-(void)setMinVoiceDuration:(float)minVoiceDuration
{
    _minVoiceDuration = minVoiceDuration;
}
- (void)startVoiceRecord
{
    if (self.recoreding == NO){
        if (self.audioRecorder == nil) {
            self.audioRecorder = [[XLCAudioRecorder alloc] initWithRootPath:self.rootPath];
            self.audioRecorder.maxVoiceDuration = self.maxVoiceDuration;
            self.audioRecorder.minVoiceDuration = self.minVoiceDuration;
            if (self.delegate && [self.delegate respondsToSelector:@selector(audioRecorderParameters)]){
                self.audioRecorder.recorderParams = [self.delegate audioRecorderParameters];
            }
            WeakSelf(weakSelf);
            self.audioRecorder.recordTimeBlock = ^(float duration) {
                StrongSelf(strongSelf);
                if (duration >= strongSelf.maxVoiceDuration) {
                    [strongSelf stopVoiceRecord];
                }
            };
        }
        if ([self.audioRecorder startRecord]) {
            self.recoreding = YES;
            [self showRecordAnimation];
        }
        else{
            self.recoreding = NO;
        }
    } 
}

- (void)stopVoiceRecord {
    if (self.audioRecorder == nil) {
        return;
    }
    if (self.recoreding) {
        [self stopRecordAnimation];
        self.recoreding = NO;
        NSURL *url = [self.audioRecorder stopRecorder];
        if (self.audioRecordCompleteBlock) {
            if (self.voiceItem == nil) {
                self.voiceItem = [[XLCvstInputMoreItemModel alloc] initWithType:MoreItemType_Voice
                                                                      titleText:@"Voice"];
            }
            self.audioRecordCompleteBlock(self.voiceItem, url);
        }
    } 
}

- (void)cancleRecord {
    [self stopRecordAnimation];
    self.recoreding = NO;
    [self.audioRecorder cancleRecorder];
}

- (void)stopRecordAnimation {
    /// 停止动画
    [self.voiceRecordGifView stopAnimating];
    [self hiddenSubviews:YES];
    self.cancleLabel.hidden = YES;
}

- (void)showRecordAnimation {
    [self hiddenSubviews:NO];
    self.cancleLabel.hidden = YES;
    /// 开启动画
    [self.voiceRecordGifView startAnimating];
}

#pragma mark  触摸事件
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    CGPoint point = [[touches anyObject] locationInView:self];
    CGRect rect = CGRectMake(0, self.frame.size.height - 49, self.frame.size.width, 49);
    if (CGRectContainsPoint(rect, point)){
        [self startVoiceRecord];
    }
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 计算位移=当前位置-起始位置
    CGPoint point = [[touches anyObject] locationInView:self];
    if (self.recoreding) {
        if (CGRectContainsPoint(self.cancleTipLabel.frame, point)){
            self.cancleLabel.hidden = NO;
            self.tipLabel.hidden = YES;
        }
        else{
            self.cancleLabel.hidden = YES;
            self.tipLabel.hidden = NO;
        }
    }
    else{
        [self hiddenSubviews:YES];
    }
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 计算位移=当前位置-起始位置
    CGPoint point = [[touches anyObject] locationInView:self];
    if (self.recoreding) {
        if (CGRectContainsPoint(self.cancleTipLabel.frame, point)){
            [self cancleRecord];
        }
        else{
            [self stopVoiceRecord];
        }
    } 
}

#pragma mark 布局

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    self.backgroundView.frame = CGRectMake(0, kXLCINaviHeight, kXLCISCREEN_WIDTH, kXLCISCREEN_HEIGHT);
    
    CGFloat width = self.frame.size.width;
    CGFloat height = self.frame.size.height;
    
    CGFloat offsetX = (self.superview.frame.size.width - self.frame.size.width) / 2.0 - self.frame.origin.x;
    
    CGFloat bgWidth = 230;
    CGFloat bgHeight = 90;
    
    CGFloat gifWidth = 168;
    CGFloat gifHeight = 48;
    
    self.voiceBackgroundView.frame = CGRectMake((width - bgWidth) / 2.0 + offsetX, height - bgWidth - 88, bgWidth, bgHeight);
    
    self.cancleLabel.frame = CGRectMake((width - 100) / 2.0 + offsetX, CGRectGetMinY(self.voiceBackgroundView.frame) - 60, 100, 40);
    
    self.voiceRecordGifView.frame = CGRectMake((bgWidth - gifWidth) / 2.0, (bgHeight - gifHeight) / 2.0, gifWidth, gifHeight);
    
    self.cancleTipLabel.frame = CGRectMake((width - 100) / 2.0 + offsetX, CGRectGetMaxY(self.voiceBackgroundView.frame) + 20, 100, 36);
    
    self.tipLabel.frame = self.cancleLabel.frame;
}

#pragma mark 录音电话

- (void)loadGIFImageNamed:(NSURL *)imageUrl {
    /// 将GIF图片转换成对应的图片资源
    CGImageSourceRef imageSourceRef = CGImageSourceCreateWithURL((__bridge CFURLRef)imageUrl,NULL);
    /// 从图片资源中获取图片帧数，即由多少图片元素组成（注：GIF图片本质是有多张图片合成流动图片）
    size_t imageCount = CGImageSourceGetCount(imageSourceRef);
    /// 定义数组拆分图片源
    NSMutableArray *images = [NSMutableArray arrayWithCapacity:imageCount];
    /// 定义动画持续时长
    float animationDuration = 0.f;
    /// 循环获取图片元素
    for(size_t i = 0; i < imageCount; i++) {
        /// 从图片资源中取出图片元素，即每一帧的图片
        CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSourceRef, i ,NULL);
        /// 图片转换
        UIImage *image = [UIImage imageWithCGImage:imageRef];
        /// 存储图片
        [images addObject:image];
        /// 初始化每帧之间间隔的属性。
        CGFloat duration = [self gifImageDeleyTime:imageSourceRef index:i];
        animationDuration += duration;
        /// 释放内存
        if(imageRef){
            CGImageRelease(imageRef);
        }
    }
    if(imageSourceRef){
        CFRelease(imageSourceRef);
    }
    /// 图片控件载入动画图片数组
    self.voiceRecordGifView.animationImages = images;
    /// 设置动画持续时长
    self.voiceRecordGifView.animationDuration = animationDuration;
    /// 设置动画重复次数
    self.voiceRecordGifView.animationRepeatCount = INT_MAX;
}
//获取GIF图片每帧的时长
- (NSTimeInterval)gifImageDeleyTime:(CGImageSourceRef)imageSource index:(NSInteger)index {
    NSTimeInterval duration = 0;
    CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, index, NULL);
    if (imageProperties) {
        CFDictionaryRef gifProperties;
        BOOL result = CFDictionaryGetValueIfPresent(imageProperties, kCGImagePropertyGIFDictionary, (const void **)&gifProperties);
        if (result) {
            const void *durationValue;
            if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFUnclampedDelayTime, &durationValue)) {
                duration = [(__bridge NSNumber *)durationValue doubleValue];
                if (duration < 0) {
                    if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFDelayTime, &durationValue)) {
                        duration = [(__bridge NSNumber *)durationValue doubleValue];
                    }
                }
            }
        }
        if(imageProperties){
            CFRelease(imageProperties);
        }
    }
    return duration;
}
#pragma mark  懒加载

- (UILabel *)cancleLabel {
    if (_cancleLabel == nil) {
        _cancleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _cancleLabel.layer.cornerRadius = 6;
        _cancleLabel.text = @"取消录音";
        _cancleLabel.textAlignment = NSTextAlignmentCenter;
        _cancleLabel.font = [UIFont fontWithName:kXLCIPingFangSC_Regular size:18];
        _cancleLabel.textColor = [UIColor colorWithRed:1.0 green:0/255.0 blue:0/255.0 alpha:1.0];
    }
    return _cancleLabel;
}
- (UILabel *)tipLabel {
    if (_tipLabel == nil) {
        _tipLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _tipLabel.layer.cornerRadius = 6;
        _tipLabel.text = @"正在录音";
        _tipLabel.textAlignment = NSTextAlignmentCenter;
        _tipLabel.font = [UIFont fontWithName:kXLCIPingFangSC_Regular size:14];
        _tipLabel.textColor = [UIColor colorWithRed:36/255.0 green:191/255.0 blue:79/255.0 alpha:1.0];
    }
    return _tipLabel;
}

- (UIView *)voiceBackgroundView {
    if (_voiceBackgroundView == nil) {
        _voiceBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
        _voiceBackgroundView.layer.cornerRadius = 6;
        _voiceBackgroundView.backgroundColor = [UIColor whiteColor];
    }
    return _voiceBackgroundView ;
}

- (UIView *)backgroundView {
    if (_backgroundView == nil) {
        _backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
        _backgroundView.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.852];
    }
    return _backgroundView ;
}

- (UIImageView *)voiceRecordGifView {
    if (_voiceRecordGifView == nil) {
        _voiceRecordGifView = [[UIImageView alloc] initWithFrame:CGRectZero];
    }
    return _voiceRecordGifView;
}

- (UILabel *)cancleTipLabel {
    if (_cancleTipLabel == nil) {
        _cancleTipLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _cancleTipLabel.layer.cornerRadius = 6;
        _cancleTipLabel.text = @"划到这里取消发送";
        _cancleTipLabel.textAlignment = NSTextAlignmentCenter;
        _cancleTipLabel.font = [UIFont fontWithName:kXLCIPingFangSC_Regular size:12];
        _cancleTipLabel.textColor = [UIColor colorWithRed:1.0 green:0/255.0 blue:0/255.0 alpha:1.0];
    }
    return _cancleTipLabel;
}

@end
